package com.css.fxfzypg.modules.resultManagement.reportReview.service.impl;

import com.css.fxfzypg.base.response.RestResponse;
import com.css.fxfzypg.constants.YNEnum;
import com.css.fxfzypg.modules.baseData.entity.HisPrEntity;
import com.css.fxfzypg.modules.baseData.repository.HisPrRepository;
import com.css.fxfzypg.modules.baseData.service.HisprService;
import com.css.fxfzypg.modules.baseData.vo.SysMenuVo;
import com.css.fxfzypg.modules.message.repository.entity.MessageEntity;
import com.css.fxfzypg.modules.message.service.MessageService;
import com.css.fxfzypg.modules.preassesstaskmanage.entity.PreAssessTaskEntity;
import com.css.fxfzypg.modules.preassesstaskmanage.service.PreAssessTaskService;
import com.css.fxfzypg.modules.resultManagement.reportManagement.entity.HistoryUploadReport;
import com.css.fxfzypg.modules.resultManagement.reportManagement.entity.ReportManagement;
import com.css.fxfzypg.modules.resultManagement.reportManagement.entity.ReviewRecord;
import com.css.fxfzypg.modules.resultManagement.reportManagement.repository.ReportManagementRepository;
import com.css.fxfzypg.modules.resultManagement.reportManagement.service.ReportManagementService;
import com.css.fxfzypg.modules.resultManagement.reportReview.repository.ReportReviewRepository;
import com.css.fxfzypg.modules.resultManagement.reportReview.service.ReportReviewService;
import com.css.fxfzypg.modules.resultManagement.reportReview.vo.ReportReviewVo;
import com.css.fxfzypg.modules.resultupload.repository.ResultTotalRepository;
import com.css.fxfzypg.modules.resultupload.repository.entity.ResultDetailsEntity;
import com.css.fxfzypg.modules.resultupload.repository.entity.ResultEntity;
import com.css.fxfzypg.modules.resultupload.repository.entity.ResultMainEntity;
import com.css.fxfzypg.modules.resultupload.service.ResultService;
import com.css.fxfzypg.modules.resultupload.service.ResultTotalService;
import com.css.fxfzypg.util.CreateGson;
import com.css.fxfzypg.util.PlatformDateUtils;
import com.css.fxfzypg.util.PlatformObjectUtils;
import com.css.fxfzypg.util.UUIDGenerator;
import com.css.fxfzypg.web.PlatformSessionContext;
import com.css.fxfzypg.zcpt.sys.entity.SUser;
import com.css.fxfzypg.zcpt.sys.service.SUserService;
import com.css.fxfzypg.zcpt.sys.service.SysAreaService;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class ReportReviewServiceImpl implements ReportReviewService {

    @Autowired
    MessageService messageService;
    @Resource
    SUserService sUserService;
    @Resource
    ReportReviewRepository reportReviewRepository;
    @Resource
    ResultService resultService;
    @Resource
    PreAssessTaskService preAssessTaskService;
    @Resource
    HisPrRepository hisPrRepository;
    @Resource
    ReportManagementRepository reportManagementRepository;
    @Resource
    ResultTotalRepository resultTotalRepository;
    @Resource
    SysAreaService sysAreaService;

    @Override
    public Map<String, Object> getPage(ReportReviewVo reportReviewVo, int curPage, int pageSize) {
        return reportReviewRepository.getPage(reportReviewVo,curPage,pageSize);
    }

    @Transactional(rollbackFor = Exception.class )
    @Override
    public Boolean review(ReportReviewVo reportReviewVo) throws IOException {
        Boolean res = false;
        String userID = PlatformSessionContext.getUserID();
        PreAssessTaskEntity preAssessTaskEntity = reportReviewRepository.getTaskIdByReportId(reportReviewVo.getReportId());//根据报告id获取预评估任务
        ReportManagement reportManagement = reportManagementRepository.getReportById(reportReviewVo.getReportId());
        String reviewStatus = reportReviewVo.getReviewStatus();
        String reportStatus = "";
        if (reviewStatus.equals("0")) {//通过
            reportStatus = "4";
            List<SysMenuVo> sysMenuList = getSAreaTree("1");//获取所有省
            String dataSource = reportManagement.getDataSource();
            if(dataSource.equals("2")){//系统计算的结果   从大页面中获取数据
                res = true;
                List<ResultMainEntity> resultMainEntities = resultTotalRepository.getResultTotalByTaskId(preAssessTaskEntity.getId(), "2");
                //入库到预评估历史数据
                if(!PlatformObjectUtils.isEmpty(resultMainEntities)){
                    for(ResultMainEntity resultMainEntity : resultMainEntities){
                        HisPrEntity hisPrEntity = new HisPrEntity();
                        hisPrEntity.setId(resultMainEntity.getId());
                        hisPrEntity.setDhpYear(preAssessTaskEntity.getTaskYear());
                        hisPrEntity.setDhpTaskName(preAssessTaskEntity.getTaskName());
                        hisPrEntity.setDhpTaskNum(preAssessTaskEntity.getTaskNum());
                        hisPrEntity.setDhpEarthquakeNum(Integer.valueOf(resultMainEntity.getSort()));
                        hisPrEntity.setDhpEpicenterLongitude(new BigDecimal(resultMainEntity.getLongitude()).setScale(2, RoundingMode.HALF_UP));
                        hisPrEntity.setDhpEpicenterLatitude(new BigDecimal(resultMainEntity.getLatitude()).setScale(2, RoundingMode.HALF_UP));
                        hisPrEntity.setDhpLocation(resultMainEntity.getMacroPosition());
                        hisPrEntity.setDhpMagnitude(resultMainEntity.getMagnitude());
                        hisPrEntity.setDhpDiArea(resultMainEntity.getDisasterArea().toString());
                        hisPrEntity.setDhpDiPeople(resultMainEntity.getDisasterNum());
                        hisPrEntity.setDhpDiGdp(resultMainEntity.getDisasterGdp());
                        hisPrEntity.setDhpEsDeath(resultMainEntity.getDeathTollAfter());
                        hisPrEntity.setDhpEsInjured(resultMainEntity.getInjuredNumAfter());
                        hisPrEntity.setDhpDiEcLosses(resultMainEntity.getDisasterLossAfter());
                        hisPrEntity.setDhpEsResNumber(resultMainEntity.getResettledNumAfter());
                        hisPrEntity.setDhpNeedEmeAssi(resultMainEntity.getRescueForceAfter());
                        hisPrEntity.setDhpProResForce(resultMainEntity.getRescueForceZyAfter());
                        hisPrEntity.setDhpCivRelEfforts(resultMainEntity.getRescueForceMjAfter());
                        hisPrEntity.setDhpOtherForces(resultMainEntity.getRescueForceQtAfter());
                        hisPrEntity.setDhpEsTentsNum(resultMainEntity.getTentNumAfter());
                        hisPrEntity.setDhpEsStretcherNum(resultMainEntity.getStretcherNumAfter());
                        hisPrEntity.setDhpEsQuiltNum(resultMainEntity.getQuiltsNumAfter());
                        hisPrEntity.setDhpEsFoodNum(resultMainEntity.getFoodsNumAfter());
                        hisPrEntity.setDhpEsWaterNum(resultMainEntity.getWaterNumAfter());
                        hisPrEntity.setDhpEsToiletNum(resultMainEntity.getBathroomNumAfter());
                        hisPrEntity.setDhpEsBathroomNum(resultMainEntity.getShowersNumAfter());
                        hisPrEntity.setDhpEsStaffNum(resultMainEntity.getMedicalMattersAfter());
                        hisPrEntity.setDhpEsDoctorNum(resultMainEntity.getMedicalNumAfter());
                        hisPrEntity.setDhpEsNurseNum(resultMainEntity.getNurseNumAfter());
                        hisPrEntity.setDhpEsPsyDoctorNum(resultMainEntity.getPsychologistAfter());
                        hisPrEntity.setDhpEsWardNum(resultMainEntity.getSickroomNumAfter());
                        hisPrEntity.setDhpEsPlasmaNum(resultMainEntity.getPlasmaNumAfter());
                        hisPrEntity.setDelFlag("0");
                        hisPrEntity.setDhpCreateUser(userID);
                        hisPrEntity.setDhpCreateTime(PlatformDateUtils.getCurrentTimestamp());
                        //根据经纬度获取省id
                        String param = resultMainEntity.getLongitude()+" "+resultMainEntity.getLatitude();
                        String provinceName = hisPrRepository.getProvinceName(param);
                        if(PlatformObjectUtils.isNotEmpty(provinceName)){
                            for(SysMenuVo sysMenuVo : sysMenuList) {
                                String name = sysMenuVo.getName();
                                if(provinceName.equals(name)){
                                    hisPrEntity.setProvinceId(sysMenuVo.getValue());
                                }
                            }
                        }
                        res = hisPrRepository.saveHisPr(hisPrEntity);
                    }
                }
            }else if(dataSource.equals("1")) {//预评估结果上传的结果   从预评估上传中获取
                res = true;
                List<ResultEntity> result = resultService.getResult(preAssessTaskEntity.getTaskNum());//根据任务编号获取 预评估上传的数据
                //入库到预评估历史数据
                if (!PlatformObjectUtils.isEmpty(result)) {
                    for (ResultEntity resultEntity : result) {
                        HisPrEntity hisPrEntity = new HisPrEntity();
                        hisPrEntity.setId(resultEntity.getId());
                        hisPrEntity.setDhpYear(preAssessTaskEntity.getTaskYear());
                        hisPrEntity.setDhpTaskName(preAssessTaskEntity.getTaskName());
                        hisPrEntity.setDhpTaskNum(resultEntity.getTaskCode());
                        hisPrEntity.setDhpEarthquakeNum(Integer.valueOf(resultEntity.getSort()));
                        hisPrEntity.setDhpEpicenterLongitude(new BigDecimal(resultEntity.getLongitude()));
                        hisPrEntity.setDhpEpicenterLatitude(new BigDecimal(resultEntity.getLatitude()));
                        hisPrEntity.setDhpLocation(resultEntity.getMacroPosition());
                        hisPrEntity.setDhpMagnitude(resultEntity.getMagnitude());
                        hisPrEntity.setDhpDiArea(resultEntity.getDisasterArea().toString());
                        hisPrEntity.setDhpDiPeople(resultEntity.getDisasterNum().toString());
                        hisPrEntity.setDhpDiGdp(resultEntity.getDisasterGDP().toString());
                        hisPrEntity.setDhpEsDeath(resultEntity.getDeathToll());
                        hisPrEntity.setDhpEsInjured(resultEntity.getInjuredNum());
                        hisPrEntity.setDhpDiEcLosses(resultEntity.getDisasterLoss());
                        hisPrEntity.setDhpEsResNumber(resultEntity.getResettledNum());
                        hisPrEntity.setDhpNeedEmeAssi(resultEntity.getRescueForce());
                        //hisPrEntity.setDhpProResForce("");
                        hisPrEntity.setDhpEsTentsNum(resultEntity.getTentNum());
                        hisPrEntity.setDelFlag("0");
                        hisPrEntity.setDhpCreateUser(userID);
                        hisPrEntity.setDhpCreateTime(PlatformDateUtils.getCurrentTimestamp());
                        //根据经纬度获取省id
                        String param = resultEntity.getLongitude() + " " + resultEntity.getLatitude();
                        String provinceName = hisPrRepository.getProvinceName(param);
                        if (PlatformObjectUtils.isNotEmpty(provinceName)) {
                            for (SysMenuVo sysMenuVo : sysMenuList) {
                                String name = sysMenuVo.getName();
                                if (provinceName.equals(name)) {
                                    hisPrEntity.setProvinceId(sysMenuVo.getValue());
                                }
                            }
                        }
                        res = hisPrRepository.saveHisPr(hisPrEntity);
                    }
                }
            }
            //审核通过 结束预评估任务
            if(res){
                preAssessTaskService.completeTask(preAssessTaskEntity.getId());
            }
        } else if (reviewStatus.equals("1")) {//不通过
            res = preAssessTaskService.updateTaskStatus("1", reportReviewVo.getReportId());//更新任务状态为进行中
            reportStatus = "2";
        }
        if(res) {
            //修改报告状态
            res = reportReviewRepository.review(reportStatus, reportReviewVo.getReviewStatus(), reportReviewVo.getReportId());
        }
        //添加到审核记录表中
        if(res){
            ReviewRecord reviewRecord = new ReviewRecord();
            reviewRecord.setId(UUIDGenerator.getUUID());
            reviewRecord.setReportId(reportReviewVo.getReportId());
            reviewRecord.setReviewStatus(reportReviewVo.getReviewStatus());
            reviewRecord.setReviewOpinion(reportReviewVo.getReviewOpinion());
            reviewRecord.setReviewTime(new Date());
            //获取到当前上传的附件,复制一份,并保存到审核表中,
            if(PlatformObjectUtils.isNotEmpty(reportManagement.getLocalUserUploadSimpleReportName())){
                String sourceFilePath = reportManagement.getReportPath() +"/"+ reportManagement.getLocalUserUploadSimpleReportName();//简本
                String localReportName = copyFile(sourceFilePath, reportManagement.getReportPath());//复制一份附件,返回复制成功的附件的名字
                reviewRecord.setUserUploadSimpleReportName(reportManagement.getUserUploadSimpleReportName());
                reviewRecord.setLocalUserUploadSimpleReportName(localReportName);
            }
            if(PlatformObjectUtils.isNotEmpty(reportManagement.getLocalUserUploadMinuteReportName())){
                String sourceFilePath = reportManagement.getReportPath() +"/"+ reportManagement.getLocalUserUploadMinuteReportName();//详本
                String localReportName = copyFile(sourceFilePath, reportManagement.getReportPath());//复制一份附件,返回复制成功的附件的名字
                reviewRecord.setUserUploadMinuteReportName(reportManagement.getUserUploadMinuteReportName());
                reviewRecord.setLocalUserUploadMinuteReportName(localReportName);
            }
            reviewRecord.setReportPath(reportManagement.getReportPath());
            res = reportReviewRepository.saveReviewRecord(reviewRecord);
        }
        //生成消息
        //当前登录人
        String userId = PlatformSessionContext.getUserID();
        String userJson = sUserService.getSUser(userId);
        SUser sUser = CreateGson.createGson().fromJson(userJson, SUser.class);
        if(res) {
            //审核通过消息
            MessageEntity messageEntity=new MessageEntity();
            //消息产生者
            messageEntity.setMessageGenerator(sUser.getUserId());
            //消息接收者
            messageEntity.setMessageReceiver(preAssessTaskEntity.getCreateUser());
            if(reviewStatus.equals("0")){
                //{任务管理员}提交了{任务名称}任务的预评估结果，请您审核。
                messageEntity.setMessageContent(preAssessTaskEntity.getTaskName()+"任务的预评估结果已审核通过");
                messageService.addMessage(messageEntity);
            }else {
                //{任务管理员}提交了{任务名称}任务的预评估结果，请您审核。
                messageEntity.setMessageContent(preAssessTaskEntity.getTaskName()+"任务的预评估结果审核未通过，未通过原因："+reportReviewVo.getReviewOpinion());
                messageService.addMessage(messageEntity);
            }
        }
        return res;
    }

    private List<SysMenuVo> getSAreaTree(String divisionId) throws UnsupportedEncodingException {
        String jsonStr = sysAreaService.jsonSAreaTree(URLEncoder.encode(divisionId, "UTF-8"));
        Gson gson = CreateGson.createGson();
        Type srItemsStandardType = new TypeToken<List<SysMenuVo>>() {
        }.getType();
        List<SysMenuVo> sysMenuList = gson.fromJson(jsonStr, srItemsStandardType);
        return sysMenuList;
    }


    @Override
    public Map<String, Object> getReviewRecordPage(ReportReviewVo reportReviewVo, int curPage, int pageSize) {
        return reportReviewRepository.getReviewRecordPage(reportReviewVo,curPage, pageSize);
    }

    public String copyFile(String sourceFilePath, String reportPath) throws IOException {
        File file = new File(sourceFilePath);
        MultipartFile multipartFile = getMultipartFile(file);
        //获取文件名称
        String fileName=multipartFile.getOriginalFilename();
        String filePrefix = fileName.split("\\.")[0];
        String fileType = fileName.split("\\.")[1];
        String localReportName = filePrefix+System.currentTimeMillis()+"."+fileType;
        String targetFilePath = reportPath + localReportName;
        File sourceFile = new File(sourceFilePath);
        File targetFile = new File(targetFilePath);
        FileInputStream inputStream = new FileInputStream(sourceFile);
        FileOutputStream outputStream = new FileOutputStream(targetFile);
        byte[] buffer = new byte[4096];
        int length = 0;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        inputStream.close();
        outputStream.close();
        return localReportName;
    }

    private MultipartFile getMultipartFile(File file){
        FileInputStream fileInputStream = null;
        MultipartFile multipartFile = null;
        try {
            fileInputStream = new FileInputStream(file);
            multipartFile = new MockMultipartFile(file.getName(),file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(),fileInputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return multipartFile;
    }
}
